home *** CD-ROM | disk | FTP | other *** search
/ TPUG - Toronto PET Users Group / TPUG Users Group CD / TPUG Users Group CD.iso / CRS / crs54.d81 / sgtool14.arc / DEMO.C < prev    next >
C/C++ Source or Header  |  1993-10-04  |  16KB  |  663 lines

  1. /*
  2. SG C Tools 1.4
  3.  
  4. (C) 1993 Steve Goldsmith
  5. All Rights Reserved
  6.  
  7. SG C Tools Demo shows how to use most of the features available with SG C
  8. Tools.
  9.  
  10. Compiled with HI-TECH C 3.09 (CP/M-80).
  11.  
  12. To compile with HI-TECH C and SG C Tools source on same disk use:
  13. C DEMO.C -LC128
  14. */
  15.  
  16. #include <stdio.h>
  17. #include <stdlib.h>
  18. #include <ctype.h>
  19. #include <conio.h>
  20. #include <sys.h>
  21. #include <stat.h>
  22. #include <cpm.h>
  23. #include <hitech.h>
  24. #include <vdc.h>
  25. #include <cia.h>
  26. #include <sid.h>
  27. #include <pcx.h>
  28.  
  29. /* 64k vdc locations */
  30.  
  31. #define appBitMapMem 0x4000
  32. #define appAttrMem   0x0800
  33.  
  34. /* colors used by this app */
  35.  
  36. #define appClockCo     vdcAltChrSet+vdcRvsVid+vdcLightCyan
  37. #define appMenuScrCo   vdcDarkBlue
  38. #define appDeskCo      vdcAltChrSet+vdcMediumGray
  39. #define appMenuTxtCo   vdcAltChrSet+vdcLightCyan
  40. #define appMenuWinCo   vdcAltChrSet+vdcLightBlue
  41. #define appIScrCo      vdcBlack
  42. #define appIDeskCo     vdcAltChrSet+vdcMediumGray
  43. #define appIWinTxtCo   vdcAltChrSet+vdcDarkBlue
  44. #define appIWinCo      vdcAltChrSet+vdcDarkYellow
  45. #define appGrTextCo    (vdcDarkGray << 4) | vdcWhite
  46. #define appSoundWinCo  vdcAltChrSet+vdcWhite
  47. #define appSoundTxt1Co vdcAltChrSet+vdcLightGreen+vdcBlink
  48. #define appSoundTxt2Co vdcAltChrSet
  49. #define appCtrlTxt1Co  vdcAltChrSet+vdcRvsVid+vdcLightYellow
  50. #define appCtrlTxt2Co  vdcAltChrSet+vdcWhite
  51. #define appCtrlWinCo   vdcAltChrSet+vdcLightCyan
  52.  
  53. extern uchar     vdcScrHorz;
  54. extern ushort    vdcDispMem;
  55. extern ushort    vdcAttrMem;
  56. extern ushort    vdcCharMem;
  57. extern ushort    vdcCharMemSize;
  58. extern ushort    vdcBitMapMemSize;
  59.  
  60. extern uchar     sidPot1X;
  61. extern uchar     sidPot1Y;
  62. extern uchar     sidPot2X;
  63. extern uchar     sidPot2Y;
  64. extern uchar     sidMouse1X;
  65. extern uchar     sidMouse1Y;
  66. extern uchar     sidMouse2X;
  67. extern uchar     sidMouse2Y;
  68.  
  69. extern uchar     ciaJoy1;
  70. extern uchar     ciaJoy2;
  71. extern ciaKeyRec ciaKeyScan;
  72.  
  73. extern ushort    pcxXSize;
  74. extern ushort    pcxYSize;
  75.  
  76. void initbitmap64k(void);
  77. void initbitmap16k(void);
  78. uchar savechrsets(void);
  79. void restorechrsets(void);
  80. void draw16khelp(uchar Rect[]);
  81. void drawmenu(uchar Rect[]);
  82. void graphicsview(void);
  83. void set64kmode(void);
  84. void ilace80x50text(void);
  85. void graphics640x200(void);
  86. void pcx640x200(char * FileName);
  87. void pcx640x480(char * FileName);
  88.  
  89. void delay(ushort D);
  90. void planesound(void);
  91. void shotssound(void);
  92. void explodesound(void);
  93. void bombdropsound(void);
  94. void soundseq(uchar Rect[], uchar Seq);
  95. void soundwin(uchar Rect[]);
  96. void playraw(char * FileName, ulong Hz);
  97.  
  98. void controlswin(uchar Rect[]);
  99. void dispclock(void);
  100.  
  101. void init(void);
  102. void run(void);
  103. void done(void);
  104.  
  105. uchar *appChSetBufPtr; /* char set buffer pointer */
  106. uchar appColors[] =    /* colors for 64k graphics */
  107. {
  108. vdcDarkGray,
  109. vdcDarkBlue,
  110. vdcLightBlue,
  111. vdcLightBlue,
  112. vdcDarkCyan,
  113. vdcDarkCyan,
  114. vdcDarkCyan,
  115. vdcLightCyan,
  116. vdcLightCyan,
  117. vdcLightCyan,
  118. vdcMediumGray,
  119. vdcMediumGray,
  120. vdcWhite,
  121. vdcMediumGray,
  122. vdcMediumGray,
  123. vdcLightCyan,
  124. vdcLightCyan,
  125. vdcLightCyan,
  126. vdcDarkCyan,
  127. vdcDarkCyan,
  128. vdcDarkCyan,
  129. vdcLightBlue,
  130. vdcLightBlue,
  131. vdcDarkBlue,
  132. vdcDarkGray
  133. };
  134.  
  135. char *appMenuItems[6] =            /* text used by this app */
  136. {
  137. "[A] Keyboard, joy stick, paddle and mouse controls",
  138. "[B] SID sound effects",
  139. "[C] Play 4 bit digitized sound",
  140. "[D] 80 X 50 interlaced text",
  141. "[E] 640 X 200 graphics",
  142. "[F] 640 X 200 PCX image, [CONTROL] & [RUN STOP] status",
  143. };
  144.  
  145. char *app16KHelp[5] =
  146. {
  147. "DO NOT select [S] option",
  148. "if your C128 has a 16K VDC!",
  149. "If you have a 64K VDC use",
  150. "[S] to get color and text",
  151. "in graphics mode!"
  152. };
  153.  
  154. char *appSoundSeq[4] =
  155. {
  156. "Plane",
  157. "Shots",
  158. "Bomb dropping",
  159. "Explosion"
  160. };
  161.  
  162. uchar appMenuRect[]    = {10,2,69,12};  /* menu window location */
  163. uchar app16KRect[]     = {24,15,56,22}; /* 16k help window location */
  164. uchar appSoundRect[]   = {19,7,59,17};  /* sound window location */
  165. uchar appControlRect[] = {10,2,69,14};  /* control window location */
  166.  
  167. ciaTODRec appTOD = {0,0,0,0}; /* used to set tod clock to 12 am */
  168.  
  169. char  appRawName[] = {"DEMO.RAW"};
  170. ulong appHz        = 8000;
  171.  
  172. char  appPcxName1[] = {"DEMO1.PCX"};
  173. char  appPcxName2[] = {"DEMO2.PCX"};
  174.  
  175. main()
  176. {
  177.   init();
  178.   run();
  179.   done();
  180. }
  181.  
  182. void initbitmap64k(void)
  183. {
  184.   setcursorvdc(0,0,vdcCurNone);    /* turn cursor off */
  185.   outvdc(vdcFgBgColor,vdcBlack);   /* black screen */
  186.   attrsoffvdc();                   /* disable attrs */
  187.   setbitmapvdc(appBitMapMem,appAttrMem,vdcBlack,vdcBlack); /* black fg bg */
  188.   mapvdc();                        /* set global vdc vars to reflect changes */
  189.   clrattrvdc(vdcBlack);
  190.   clrbitmapvdc(0);                 /* clear bit map */
  191.   attrsonvdc();                    /* enable attrs */
  192. }
  193.  
  194. void initbitmap16k(void)
  195. {
  196.   setcursorvdc(0,0,vdcCurNone);    /* turn cursor off */
  197.   outvdc(vdcFgBgColor,vdcBlack);   /* black screen */
  198.   attrsoffvdc();                   /* disable attrs to work on 16k vdc */
  199.   setbitmapvdc(vdcDispMem,vdcAttrMem,vdcWhite,vdcBlack);
  200.   clrbitmapvdc(0);                 /* clear bit map */
  201. }
  202.  
  203. uchar savechrsets(void)
  204. {
  205.   if(is64kvdc())
  206.     return(1);
  207.   else
  208.   {
  209.     appChSetBufPtr = memtobufvdc(vdcCharMem,vdcCharMemSize);
  210.     if (appChSetBufPtr != NULL)
  211.       return(1);
  212.     else
  213.       return(0);
  214.   }
  215. }
  216.  
  217. void restorechrsets(void)
  218. {
  219.   if(appChSetBufPtr != NULL)
  220.   {
  221.     outvdc(vdcFgBgColor,vdcBlack); /* set foreground-background to black */
  222.     attrsoffvdc();                 /* disable attrs */
  223.     buftomemvdc(appChSetBufPtr,vdcCharMem,vdcCharMemSize);
  224.   }
  225. }
  226.  
  227. void draw16khelp(uchar Rect[])
  228. {
  229.   uchar I;
  230.  
  231.   winvdc(Rect[0],Rect[1],Rect[2],Rect[3],appMenuWinCo,"VDC Help");
  232.   for(I=0; I < 5; I++)
  233.     printstrvdc(Rect[0]+2,Rect[1]+I+2,appMenuTxtCo,app16KHelp[I]);
  234. }
  235.  
  236. void drawmenu(uchar Rect[])
  237. {
  238.   uchar I;
  239.  
  240.   outvdc(vdcFgBgColor,appMenuScrCo); /* set new screen color */
  241.   setcursorvdc(0,0,vdcCurNone);      /* turn cursor off */
  242.   clrattrvdc(appDeskCo);             /* draw desk top */
  243.   clrscrvdc(137);
  244.   filldspvdc(0,0,vdcScrHorz,32);
  245.   fillattrvdc(0,0,vdcScrHorz,appClockCo);
  246.   printstrvdc(1,0,appClockCo,"CP/M");
  247.   printstrvdc(67,0,appClockCo,"RUN");
  248.   winvdc(Rect[0],Rect[1],Rect[2],Rect[3],appMenuWinCo,"SG C Tools 1.4 Demo (C) 1993");
  249.   for(I=0; I < 6; I++)
  250.     printstrvdc(Rect[0]+2,Rect[1]+I+2,appMenuTxtCo,appMenuItems[I]);
  251.   if(is64kvdc())
  252.     printstrvdc(Rect[0]+2,Rect[3]-2,appMenuTxtCo,"[G] 640 X 480 interlace PCX image");
  253.   else
  254.   {
  255.     printstrvdc(Rect[0]+2,Rect[3]-2,appMenuTxtCo,"[S] Set 64K mode");
  256.     draw16khelp(app16KRect);
  257.   }
  258.   printstrvdc(Rect[0]+2,Rect[3]-1,appMenuTxtCo,"[X] Exit to CP/M");
  259. }
  260.  
  261. void graphicsview(void) /* view graphics until key pressed */
  262. {
  263.   while (!(kbhit()));
  264.   getch();
  265.   outvdc(vdcFgBgColor,vdcBlack);
  266.   attrsoffvdc();
  267.   restorechrsets();
  268.   restorevdc();
  269.   mapvdc();
  270.   drawmenu(appMenuRect);
  271. }
  272.  
  273. void set64kmode(void)
  274. {
  275.   if(!(is64kvdc()) && appChSetBufPtr != NULL)
  276.   {
  277.     restorevdc();         /* make sure all registers are default value */
  278.     set64kvdc();          /* set 64k mode */
  279.     savevdc();            /* reflect change to reg 28 */
  280.     restorechrsets();     /* restore char sets destroyed by setting 64k mode */
  281.     free(appChSetBufPtr); /* dispose buffer */
  282.     appChSetBufPtr = NULL;
  283.     restorevdc();
  284.     mapvdc();
  285.     drawmenu(appMenuRect);
  286.   }
  287. }
  288.  
  289. void ilace80x50text(void)
  290. {
  291.   uchar I;
  292.  
  293.   outvdc(vdcFgBgColor,appIScrCo); /* set new screen color */
  294.   setdsppagevdc(vdcDispMem,vdcAttrMem << 1);
  295.   set80x50textvdc();
  296.   mapvdc();                       /* map changes */
  297.   clrattrvdc(appIDeskCo);
  298.   clrscrvdc(137);
  299.   winvdc(10,5,69,44,appIWinCo,"Interlace 80 X 50 Mode");
  300.   printstrvdc(11,43,appIWinTxtCo,
  301.   "All functions that operate in 80 X 25 work in 80 X 50 too!");
  302.   for (I = 1; I <= 36; I++)       /* scroll window */
  303.     scrollupvdc(11,7,68,43);
  304.   while (!(kbhit()));
  305.   getch();
  306.   clrattrvdc(vdcAltChrSet);
  307.   clrscrvdc(32);
  308.   restorevdc();
  309.   mapvdc();
  310.   drawmenu(appMenuRect);
  311. }
  312.  
  313. void graphics640x200(void)
  314. {
  315.   int I;
  316.   uchar X, Y;
  317.  
  318.   vdcBitMapMemSize = 16000;
  319.   if(is64kvdc())
  320.   {
  321.     initbitmap64k();
  322.     for(I = 0; I <= sizeof(appColors); I++)
  323.       fillattrvdc(0,I,vdcScrHorz,appColors[I]);
  324.   }
  325.   else
  326.     initbitmap16k();
  327.   for(I = 0; I <= 639; I += 40)
  328.   {
  329.     linevdc(319,0,I,199);
  330.     linevdc(I,0,319,199);
  331.   }
  332.   for(I = 0; I <= 199; I += 32)
  333.   {
  334.     circlevdc(319,99,I);
  335.   }
  336.   if(is64kvdc())
  337.   {
  338.     printbmvdc(12,1,appGrTextCo,
  339.     "SG C Tools makes it easy to use text in GRAPHICS mode!");
  340.     printbmvdc(32,3,appGrTextCo,"Bit map colors");
  341.     for (Y = 0; Y < 16; Y++)
  342.       for (X = 0; X < 16; X++)
  343.         printbmvdc(X+31,Y+5,(Y << 4) | X,"*");
  344.   }
  345.   graphicsview();
  346. }
  347.  
  348. void pcx640x200(char * FileName)
  349. {
  350.   bdos(45,0x0FE);
  351.   if (initpcx(FileName) == pcxErrNone)
  352.   {
  353.     if (pcxXSize < 641 && pcxYSize < 201)
  354.     {
  355.       vdcBitMapMemSize = 16000;
  356.       if(is64kvdc())
  357.       {
  358.         initbitmap64k();
  359.         clrattrvdc(vdcWhite);
  360.       }
  361.       else
  362.         initbitmap16k();
  363.       decodefilepcx(0,0);
  364.       donepcx();
  365.       graphicsview();
  366.     }
  367.     else
  368.       donepcx();
  369.   }
  370. }
  371.  
  372. void pcx640x480(char * FileName)
  373. {
  374.   if(is64kvdc())
  375.   {
  376.     bdos(45,0x0FE);
  377.     if (initpcx(FileName) == pcxErrNone)
  378.     {
  379.       if (pcxXSize < 641 && pcxYSize < 481)
  380.       {
  381.         vdcBitMapMemSize = 49152;
  382.         attrsoffvdc();
  383.         setbitmapintvdc(appBitMapMem,appAttrMem,vdcBlack,vdcBlack);
  384.         mapvdc();
  385.         clrbitmapvdc(0);
  386.         outvdc(vdcFgBgColor,vdcDarkBlue << 4);
  387.         decodefileintpcx(0,0);
  388.         donepcx();
  389.         graphicsview();
  390.       }
  391.       else
  392.         donepcx();
  393.     }
  394.   }
  395. }
  396.  
  397. void delay(ushort D) /* delay in milliseconds (1/1000 sec) */
  398. {
  399.   setintctrlcia(cia2,ciaClearIcr); /* disable all cia 2 interrupts */
  400.   settimerbcia(cia2,D,ciaCountA);  /* timer b counts timer a underflows */
  401.   settimeracia(cia2,timervalcia(1000),ciaCPUCont); /* set timer a 1/1000 sec */
  402.   while ((inp(cia2+ciaIntCtrl) & 0x02) == 0);      /* wait for count down */
  403. }
  404.  
  405. void planesound(void)
  406. {
  407.   ushort Pulse;
  408.   ushort Freq = 2047;
  409.  
  410.   volumesid(15,0);
  411.   envelopesid(sidVoice1,12,10,0,0);
  412.   attacksid(sidVoice1,sidWaveSqu);
  413.   for(Pulse = 0; Pulse < 3840; Pulse += 10)
  414.   {
  415.     pulsewavesid(sidVoice1,Pulse);
  416.     freqsid(sidVoice1,Freq);
  417.     Freq -= 5;
  418.     delay(2);
  419.   }
  420.   releasesid(sidVoice1,sidWaveSqu);
  421.   delay(6);
  422.   freqsid(sidVoice1,0);
  423. }
  424.  
  425. void shotssound(void)
  426. {
  427.   uchar I;
  428.  
  429.   volumesid(15,0);
  430.   for(I = 0; I < 20; I++)
  431.   {
  432.     envelopesid(sidVoice1,0,3,0,0);
  433.     freqsid(sidVoice1,5360);
  434.     attacksid(sidVoice1,sidWaveNoi);
  435.     delay(100);
  436.     releasesid(sidVoice1,sidWaveNoi);
  437.     delay(6);
  438.   }
  439.   freqsid(sidVoice1,0);
  440. }
  441.  
  442. void explodesound(void)
  443. {
  444.   volumesid(15,0);
  445.   envelopesid(sidVoice1,0,0,15,11);
  446.   freqsid(sidVoice1,200);
  447.   attacksid(sidVoice1,sidWaveNoi);
  448.   delay(8);
  449.   releasesid(sidVoice1,sidWaveNoi);
  450.   delay(2400);
  451.   freqsid(sidVoice1,0);
  452. }
  453.  
  454. void bombdropsound(void)
  455. {
  456.   ushort I;
  457.  
  458.   volumesid(15,0);
  459.   envelopesid(sidVoice3,13,0,15,0);
  460.   freqsid(sidVoice3,0);
  461.   attacksid(sidVoice3,sidWaveTri);
  462.   for(I = 32000; I > 200; I -= 200)
  463.   {
  464.     freqsid(sidVoice3,I);
  465.     delay(18);
  466.   }
  467.   releasesid(sidVoice3,sidWaveTri);
  468.   delay(6);
  469.   freqsid(sidVoice3,0);
  470. }
  471.  
  472. void soundseq(uchar Rect[], uchar Seq)
  473. {
  474.   scrollupvdc(Rect[0]+1,Rect[1]+2,Rect[2]-1,Rect[3]-1);
  475.   fillattrvdc(Rect[0]+2,Rect[3]-3,Rect[2]-Rect[0]-2,appSoundTxt2Co);
  476.   printstrvdc(Rect[0]+2,Rect[3]-2,appSoundTxt1Co,appSoundSeq[Seq]);
  477. }
  478.  
  479. void soundwin(uchar Rect[])
  480. {
  481.   uchar I;
  482.  
  483.   winvdc(Rect[0],Rect[1],Rect[2],Rect[3],appSoundWinCo,"SID Sound Effects");
  484.   for(I = 0; I < 4; I++)
  485.   {
  486.     soundseq(Rect,I);
  487.     switch (I)
  488.     {
  489.       case 0 :
  490.         planesound();
  491.         break;
  492.       case 1 :
  493.         shotssound();
  494.         break;
  495.       case 2 :
  496.         bombdropsound();
  497.         break;
  498.       case 3 :
  499.         explodesound();
  500.         break;
  501.     }
  502.   }
  503.   drawmenu(appMenuRect);
  504. }
  505.  
  506. void playraw(char * FileName, ulong Hz)
  507. {
  508.   uchar  *RawBufPtr;
  509.   FILE   *RawFile;
  510.   ulong  RawSize;
  511.   struct stat  StatRec;
  512.  
  513.   RawBufPtr = NULL;
  514.   bdos(45,0x0FE);
  515.   if (stat(FileName,&StatRec) == 0)
  516.     RawSize = StatRec.st_size;
  517.   else
  518.     RawSize = 0;
  519.   if (RawSize > 0)
  520.   {
  521.     RawBufPtr = (uchar *) malloc(RawSize);
  522.     if (RawBufPtr != NULL)
  523.     {
  524.       if ((RawFile = fopen(FileName,"rb")) != NULL)
  525.       {
  526.         fread(RawBufPtr,sizeof(uchar),RawSize,RawFile);
  527.         fclose(RawFile);
  528. #asm
  529.   di
  530. #endasm
  531.         setintctrlcia(cia2,ciaClearIcr);
  532.         settimeracia(cia2,timervalcia(Hz),ciaCPUCont);
  533.         playzb4sid(RawBufPtr,RawSize);
  534. #asm
  535.   ei
  536. #endasm
  537.       }
  538.       free(RawBufPtr);
  539.     }
  540.   }
  541. }
  542.  
  543. void controlswin(uchar Rect[])
  544. {
  545.   char  StrBuf[45];
  546.  
  547.   winvdc(Rect[0],Rect[1],Rect[2],Rect[3],appCtrlWinCo,"Controls");
  548.   printstrvdc(Rect[0]+2,Rect[1]+2,appCtrlTxt1Co,"Keyboard   0   1   2   3   4   5   6   7   8   9   10 ");
  549.   printstrvdc(Rect[0]+2,Rect[1]+4,appCtrlTxt1Co,"Joystick   1   2  ");
  550.   printstrvdc(Rect[0]+2,Rect[1]+6,appCtrlTxt1Co,"Paddle     1   2   3   4  ");
  551.   printstrvdc(Rect[0]+2,Rect[1]+8,appCtrlTxt1Co,"1351 Mouse X1  Y1  X2  Y2 ");
  552.   printstrvdc(Rect[0]+21,Rect[1]+11,appCtrlTxt2Co | vdcBlink,
  553.   " [RUN STOP] to exit ");
  554. #asm
  555.   di
  556. #endasm
  557.   do
  558.   {
  559.     getpotssid();  /* read controls */
  560.     getmousesid();
  561.     getjoyscia();
  562.     getkeyscia();
  563.  
  564.     sprintf(StrBuf,"%4u%4u%4u%4u%4u%4u%4u%4u%4u%4u%4u",
  565.     ciaKeyScan[0],ciaKeyScan[1],ciaKeyScan[2],ciaKeyScan[3],
  566.     ciaKeyScan[4],ciaKeyScan[5],ciaKeyScan[6],ciaKeyScan[7],
  567.     ciaKeyScan[8],ciaKeyScan[9],ciaKeyScan[10]);
  568.     printstrvdc(Rect[0]+12,Rect[1]+3,appCtrlTxt2Co,StrBuf);
  569.  
  570.     sprintf(StrBuf,"%4u%4u",ciaJoy1,ciaJoy2);
  571.     printstrvdc(Rect[0]+12,Rect[1]+5,appCtrlTxt2Co,StrBuf);
  572.  
  573.     sprintf(StrBuf,"%4u%4u%4u%4u",sidPot1X,sidPot1Y,sidPot2X,sidPot2Y);
  574.     printstrvdc(Rect[0]+12,Rect[1]+7,appCtrlTxt2Co,StrBuf);
  575.  
  576.     sprintf(StrBuf,"%4u%4u%4u%4u",sidMouse1X,sidMouse1Y,sidMouse2X,sidMouse2Y);
  577.     printstrvdc(Rect[0]+12,Rect[1]+9,appCtrlTxt2Co,StrBuf);
  578.   }
  579.   while(ciaKeyScan[7] != 127);
  580. #asm
  581.   ei
  582. #endasm
  583.   drawmenu(appMenuRect);
  584. }
  585.  
  586. void dispclock(void)
  587. {
  588.   ciaTODStr TODStr;
  589.  
  590.   gettodcia(cia1,appTOD);
  591.   todstrcia(appTOD,TODStr);
  592.   printstrvdc(6,0,appClockCo,TODStr);
  593.   gettodcia(cia2,appTOD);
  594.   todstrcia(appTOD,TODStr);
  595.   TODStr[8] = 0;                          /* get rid of am/pm extension */
  596.   printstrvdc(71,0,appClockCo,TODStr);
  597. }
  598.  
  599. void init(void)
  600. {
  601.   settodcia(cia2,appTOD);
  602.   clearsid();
  603.   savevdc();
  604.   mapvdc();
  605.   appChSetBufPtr = NULL;
  606. }
  607.  
  608. void run(void)
  609. {
  610.   char  InKey;
  611.  
  612.   winvdc(21,5,58,10,vdcAltChrSet+vdcDarkGreen,"Info");
  613.   printstrvdc(23,7,vdcAltChrSet+vdcBlink+vdcLightGreen,
  614.   "Saving character sets to buffer");
  615.   if(savechrsets())     /* check if vdc in 16k mode */
  616.   {
  617.     drawmenu(appMenuRect);
  618.     do
  619.     {
  620.       while (!(kbhit()))
  621.         dispclock();
  622.       InKey = toupper(getch());
  623.       switch (InKey)
  624.       {
  625.         case 'A':
  626.           controlswin(appControlRect);
  627.           break;
  628.         case 'B':
  629.           soundwin(appSoundRect);
  630.           break;
  631.         case 'C':
  632.           playraw(appRawName,appHz);
  633.           break;
  634.         case 'D':
  635.           ilace80x50text();
  636.           break;
  637.         case 'E':
  638.           graphics640x200();
  639.           break;
  640.         case 'F':
  641.           pcx640x200(appPcxName1);
  642.           break;
  643.         case 'G':
  644.           pcx640x480(appPcxName2);
  645.           break;
  646.         case 'S':
  647.           set64kmode();
  648.           break;
  649.       }
  650.     }
  651.     while (InKey != 'X');
  652.   }
  653. }
  654.  
  655. void done(void)
  656. {
  657.   clearsid();
  658.   if(appChSetBufPtr != NULL)
  659.     free(appChSetBufPtr);
  660.   restorevdc();     /* restore registers saved by savevdc() */
  661.   putchar(0x1A);    /* adm-3a clear-home cursor */
  662. }
  663.